;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; DEFINE PLOT-OBJECTS WITH VISTA-6 LOOK & FEEL
;;
;; residual-plot, influence-plot, added-var-plot, iter-plot-proto
;; robust-reg-plot, fit-plot, and obs-plot
;;
;; all plots except obs inherit from vista-scatterplot-proto
;;
;; all plots defined here except lsmt and simple-reg
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; residual-plot-proto
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defproto residual-plot-proto '(spreadplot-supervisor showing)
  '() vista-scatterplot-proto)

(defmeth residual-plot-proto :spreadplot-supervisor (&optional (obj-id nil set)) 
  (when set (setf (slot-value 'spreadplot-supervisor) obj-id)) 
  (slot-value 'spreadplot-supervisor))

(defmeth residual-plot-proto :showing (&optional (obj-id nil set)) 
  (when set (setf (slot-value 'showing) obj-id)) 
  (slot-value 'showing))

(defmeth residual-plot-proto :show-plot ()
  (send self :show-window)
  (send self :showing t))

(defmeth residual-plot-proto :new-y () 
  (send self :change-y-axis))

(defmeth residual-plot-proto :change-y-axis ()
  (send (send self :spreadplot-supervisor) :get-residuals self))

(defun residual-plot (spreadplot-supervisor x y &rest args)
  (apply #'send residual-plot-proto :new spreadplot-supervisor x y args))


(defmeth residual-plot-proto :isnew
  (spreadplot-supervisor x y
     &rest args
     &key
     (title "Residuals")
     (menu-title "Resid")
     (scale 'nil)
     (show 't)
     showing)
  (let ((labels (send (send spreadplot-supervisor :model) :labels)))
    (send self :spreadplot-supervisor spreadplot-supervisor)
    (apply #'call-next-method 2 
           (append args `(:title ,title :menu-title ,menu-title :show nil)))
  ;  (when (not (send spreadplot-supervisor :simple-reg))
  ;        (send self :plot-buttons :new-x nil :new-y nil :mouse-mode nil))
    (send self :add-points x y :point-labels labels :draw 'nil)
    #+color(when (> *color-mode* 0)
                 (send self :use-color t)
                 (send self :point-color 
                       (iseq (send self :num-points)) 'blue))
    (send self :adjust-to-data :draw 'nil)
    (send self :abline 0.0 0.0)
    (if show (send self :show-window))
    ))

(defmeth residual-plot-proto :close ()
  (send (send self :spreadplot-supervisor) :close-dialog self))

(defmeth residual-plot-proto :obs-plots ()
  (let ((splot (send self :spreadplot-supervisor)))
    (when splot (send splot :obs-plots))))        

(defmeth residual-plot-proto :links ()
  (let ((obs-plots (send self :obs-plots)))
    (if (member self obs-plots) obs-plots)))

(defmeth residual-plot-proto :linked (&optional (link nil set))
  (let ((obs-plots (send self :obs-plots)))
    (when set (setf obs-plots (if link (cons self obs-plots)
                                  (remove self obs-plots)))
          (call-next-method link))
    (call-next-method)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; influence-plot-proto
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defproto influence-plot-proto '(spreadplot-supervisor showing)
  '() vista-scatterplot-proto)

(defmeth influence-plot-proto :spreadplot-supervisor (&optional (obj-id nil set)) 
  (when set (setf (slot-value 'spreadplot-supervisor) obj-id)) 
  (slot-value 'spreadplot-supervisor))

(defmeth influence-plot-proto :showing (&optional (obj-id nil set)) 
  (when set (setf (slot-value 'showing) obj-id)) 
  (slot-value 'showing))

(defmeth influence-plot-proto :show-plot ()
  (send self :show-window)
  (send self :showing t))

(defmeth influence-plot-proto :new-y () (send self :change-y-axis))

(defmeth influence-plot-proto :change-y-axis ()
  (send (send self :spreadplot-supervisor) :get-influence self))

(defun influence-plot (spreadplot-supervisor x y &rest args)
  (apply #'send influence-plot-proto :new spreadplot-supervisor x y args))


(defmeth influence-plot-proto :isnew
  (spreadplot-supervisor x y
     &rest args
     &key
     (title "Influence")
     (menu-title "Influence")
     (scale 'nil)
     (show 't)
     showing)
  (let ((labels (send (send spreadplot-supervisor :model) :labels)))
    (send self :spreadplot-supervisor spreadplot-supervisor)
    (apply #'call-next-method 2 
           (append args `(:title ,title :menu-title ,menu-title :show nil)))
   ; (when (not (send spreadplot-supervisor :simple-reg))
   ;       (send self :plot-buttons :new-x nil :new-y nil))
    (send self :add-points x y :point-labels labels :draw 'nil)
    #+color(when (> *color-mode* 0)
                 (send self :use-color t)
                 (send self :point-color 
                       (iseq (send self :num-points)) 'blue))
    (send self :adjust-to-data :draw 'nil)
    (if show (send self :show-window))
    ))

(defmeth influence-plot-proto :close ()
  (send (send self :spreadplot-supervisor) :close-dialog self))

(defmeth influence-plot-proto :obs-plots ()
  (let ((splot (send self :spreadplot-supervisor)))
    (when splot (send splot :obs-plots))))        

(defmeth influence-plot-proto :links ()
  (let ((obs-plots (send self :obs-plots)))
    (if (member self obs-plots) obs-plots)))

(defmeth influence-plot-proto :linked (&optional (link nil set))
  (let ((obs-plots (send self :obs-plots)))
    (when set (setf obs-plots (if link (cons self obs-plots)
                                  (remove self obs-plots)))
          (call-next-method link))
    (call-next-method)))

;;=========================================
;; Fit Plot (lin-reg-plot-proto)
;;=========================================

(defproto lin-reg-plot-proto '(spreadplot-supervisor showing)
  '() vista-scatterplot-proto)

(defmeth lin-reg-plot-proto :spreadplot-supervisor (&optional (obj-id nil set)) 
  (when set (setf (slot-value 'spreadplot-supervisor) obj-id)) 
  (slot-value 'spreadplot-supervisor))

(defmeth lin-reg-plot-proto :showing (&optional (obj-id nil set)) 
  (when set (setf (slot-value 'showing) obj-id)) 
  (slot-value 'showing))

(defmeth lin-reg-plot-proto :show-plot ()
  (send self :show-window)
  (send self :showing t))

(defun lin-reg-plot (spreadplot-supervisor x y &rest args)
  (apply #'send lin-reg-plot-proto :new spreadplot-supervisor x y args))

(defmeth lin-reg-plot-proto :isnew
  (spreadplot-supervisor x y
     &rest args
     &key
     (title "Fit")
     (menu-title "Fit")
     (scale 'nil)
     (show 't)
     showing)
  (let* ((model (send spreadplot-supervisor :model))
         (dv2 (select (send model :variables) (send model :dv)))
         (dv (if (listp dv2) (select dv2 0) dv2)))
    (send self :spreadplot-supervisor spreadplot-supervisor)
    (apply #'call-next-method 2 
           (append args `(:title ,title :menu-title ,menu-title 
                                 :show nil)))
    (send self :variable-label '(0 1)
          (list (strcat "Fitted " dv) dv))
    
    (send self :add-points x y)
    #+color(when (> *color-mode* 0)
                 (send self :use-color t)
                 (send self :point-color 
                       (iseq (send self :num-points)) 'blue))
     (send self :make-scatterplot-curves)
    (send self :switch-add-normal :contour-values (list 1.5) :axes nil)
    (send self :switch-add-linear)
    (send self :kernel-line-type 0)
    (send self :switch-add-kernel-line)
    (send self :adjust-to-data)
    
    (send self :linked t)
    (if show (send self :show-window))
    ))

(defmeth lin-reg-plot-proto :close ()
  (send (send self :spreadplot-supervisor) :close-dialog self))

(defmeth lin-reg-plot-proto :obs-plots ()
  (let ((splot (send self :spreadplot-supervisor)))
    (when splot (send splot :obs-plots))))        

(defmeth lin-reg-plot-proto :links ()
  (let ((obs-plots (send self :obs-plots)))
    (if (member self obs-plots) obs-plots)))

(defmeth lin-reg-plot-proto :linked (&optional (link nil set))
  (let ((obs-plots (send self :obs-plots)))
    (when set (setf obs-plots (if link (cons self obs-plots)
                                  (remove self obs-plots)))
          (call-next-method link))
    (call-next-method)))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ADDED VARIABLE PLOT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun added-var-plot (spreadplot-supervisor x y  
                       &key (show nil) (simple-reg nil))
  (if simple-reg
      (send simple-reg-plot-proto 
             :new spreadplot-supervisor x y :show show)
      (send added-var-plot-proto 
             :new spreadplot-supervisor x y :show show)))

(defproto added-var-plot-proto 
  '(spreadplot-supervisor showing x simple-reg 
      show-resid-lines contours contour-values dialog)
  '() vista-scatterplot-proto)

(defmeth added-var-plot-proto :spreadplot-supervisor (&optional (obj-id nil set)) 
  (when set (setf (slot-value 'spreadplot-supervisor) obj-id)) 
  (slot-value 'spreadplot-supervisor))

(defmeth added-var-plot-proto :showing (&optional (obj-id nil set)) 
  (when set (setf (slot-value 'showing) obj-id)) 
  (slot-value 'showing))

(defmeth added-var-plot-proto :x (&optional (value nil set)) 
  (when set (setf (slot-value 'x) value)) 
  (slot-value 'x))

(defmeth added-var-plot-proto :simple-reg (&optional (logical nil set)) 
  (when set (setf (slot-value 'simple-reg) logical)) 
  (slot-value 'simple-reg))

(defmeth added-var-plot-proto :dialog (&optional (value nil set)) 
  (when set (setf (slot-value 'dialog) value)) 
  (slot-value 'dialog))

(defmeth added-var-plot-proto :show-plot ()
  (send self :show-window)
  (send self :showing t))

(defmeth added-var-plot-proto :isnew
  (spreadplot-supervisor x y &key (show nil) (simple-reg nil))
  (let* ((mod (send spreadplot-supervisor :model))
         (labels (send mod :labels))
         (range)
         (R (correlation x y))
         )
    (send self :scale-type nil)
    (send self :spreadplot-supervisor spreadplot-supervisor)
    (send self :simple-reg simple-reg)
    (when simple-reg (setf title "Data with Regression"))
    (apply #'call-next-method (combine 2 x y :title "Added Variable Plot" ))
    (send self :menu-title "AddVar")
    (send self :use-color t)
    (send self :add-points x y :point-labels labels :draw 'nil)
    (send self :adjust-to-data)
    (send self :make-scatterplot-curves)
    (send self :regvalues-list nil)
    (send self :switch-add-regline)
    (send self :switch-add-regmeanline)
   ; (defmeth self :redraw ()
   ;   (call-next-method)
   ;   (send self :draw-legends))
    (when (not simple-reg)
          (send self :get-added-var self 0))
    ))

(defmeth added-var-plot-proto :close ()
  (send (send self :spreadplot-supervisor) :close-dialog self))

(defmeth added-var-plot-proto :obs-plots ()
  (let ((splot (send self :spreadplot-supervisor)))
    (when splot (send splot :obs-plots))))        

(defmeth added-var-plot-proto :links ()
  (let ((obs-plots (send self :obs-plots)))
    (if (member self obs-plots) obs-plots)))

(defmeth added-var-plot-proto :linked (&optional (link nil set))
  (let ((obs-plots (send self :obs-plots)))
    (when set (setf obs-plots (if link (cons self obs-plots)
                                  (remove self obs-plots)))
          (call-next-method link))
    (call-next-method)))

(defmeth morals-spreadplot-supervisor-proto :get-added-var (plot &optional varnum)
  (send plot :get-added-var plot varnum))

(defmeth morals-spreadplot-supervisor-proto :update-added-var-plot 
  (plot value datamat y dv nobs num mod)
  (send plot :update-added-var-plot value datamat y dv nobs num mod))

(defmeth added-var-plot-proto :get-added-var (plot &optional varnum)
  (let* ((splot (send self :spreadplot-supervisor))
         (mod (send splot :model))
         (model (send mod :morals-model))
         (y (send model :y))
         (datamat (send model :x))
         (nobs (send mod :nobs))
         (num (iseq (select (array-dimensions datamat) 1)))
         (dv2 (select (send mod :variables) (send mod :dv)))
         (dv (if (listp dv2) (select dv2 0) dv2))
         )
    (when varnum (send self :update-added-var-plot 
                       varnum datamat y dv nobs num mod))
    ))

(defmeth added-var-plot-proto  :update-added-var-plot 
  (value datamat y dv nobs num mod &optional regline regresiduals lsmt)
  (if (not value) (setf value (send self :x)))
  (if (not (numberp value)) (setf value 0))
  (let* ((plot self)
         (splot (send self :spreadplot-supervisor))
         (x (combine (select datamat (iseq nobs) value)))
         (num (remove value num))
         (otherxs (select datamat (iseq nobs) num))
         (point-labels (send mod :labels))
         (npts (send plot :num-points))
         (point-colors (send plot :point-color (iseq npts)))
         (point-symbols (send plot :point-symbol (iseq npts)))
         (point-states (send plot :point-state (iseq npts)))
         (rw nil)
         (yx nil)
         (xx nil)
         (coefs)
         (colors)
         (shapes)
         )

    (cond
      ((equal (send mod :method) "Robust")
       (setf rw (first (last (send (send (send splot :model) :robust-model) 
                                   :weight-list))))
       (setf yx (regression-model otherxs y :weights rw :print nil))
       (setf xx (regression-model otherxs x :weights rw :print nil)))
      (t
       (setf yx (regression-model otherxs y :print nil))
       (setf xx (regression-model otherxs x :print nil))))
    (setf coefs (send yx :coef-estimates))
    (send plot :x value)
    (send plot :start-buffering)
    (send plot :clear :draw nil)
    (send plot :add-points (send xx :residuals)
          (send yx :residuals) :point-labels point-labels :point-colors point-colors
          :point-symbols point-symbols :point-states point-states :draw nil)
    (apply #'send plot :point-color (iseq npts) point-colors)
    (apply #'send plot :point-symbol (iseq npts) point-symbols)
    (apply #'send plot :point-state (iseq npts) point-states)

    (send self :adjust-to-data)
   ; (send self :make-scatterplot-curves)
    (send self :regvalues-list nil)
    (send self :add-lsmt? lsmt)
    (send self :add-regresiduals? regresiduals)
    (send self :add-regline? regline)
    (send plot :redraw-curves)
    (if (equal (send mod :method) "Monotonic")
        (send plot :variable-label '(0 1) (list (strcat (select 
          (send mod :variables) (select (send mod :iv) value))
                       "|Other Predictors") (strcat "Linearized-" dv "|Other Predictors"))) 
        (send plot :variable-label '(0 1) (list (strcat (select 
          (send mod :variables) (select (send mod :iv) value))
                       "|Other Predictors") (strcat dv "|Other Predictors"))))
   
    (send plot :buffer-to-screen)
    ))


;;=========================================
;; iter plot (iter-plot-proto) 
;; Used by RSq-Beta and Robust iteration plots
;;=========================================


(defun rsq-plot (spreadplot-supervisor diff-plot? &rest args)
  (apply #'send iter-plot-proto :new 
         spreadplot-supervisor diff-plot? t  args))

(defun robust-plot (spreadplot-supervisor diff-plot? &rest args)
  (apply #'send iter-plot-proto :new 
         spreadplot-supervisor diff-plot? nil args))

(defproto iter-plot-proto 
  '(spreadplot-supervisor showing diff-plot rsq?) ()
  vista-scatterplot-proto ())

(setf *rsq-plots* nil)

(defmeth iter-plot-proto :isnew 
          (ssp  diff-plot? rsq? &rest args &key (title nil) 
               (menu-title nil) (scale) (show t))
  (let* ((all-args (append (list 2) args '(:show nil))))
    (apply #'call-next-method all-args)
    (send self :rsq? rsq?)
    (send self :spreadplot-supervisor ssp)
    (send self :diff-plot diff-plot?)  ;????????????
    (let ((ovr (send self :overlays)))
      (when ovr
           (send (first ovr) :remove-button ':mouse-mode)
           (send (first ovr) :remove-button ':zoom)
           (send (first ovr) :remove-button ':pop)
           ))
    (cond
      (rsq? (send self :title (if title title "R-Sq and |Beta|"))
            (send self :menu-title (if menu-title menu-title "RSq-Beta")))
      (t (send self :title (if title title "Robust Weights"))
         (send self :menu-title (if menu-title menu-title "Robust"))))
    (send self :new-menu nil)
    (send self :menu nil)
    (send self :variable-label 0 "Iterations")
    (send self :variable-label 1 "Value")
    (send self :range 1 0 1)
    (send self :y-axis t t 3)
    (send self :margin -10 20 -25 -10)
    (when show (send self :show-window)
          (send self :showing t))
    self ))


(defmeth iter-plot-proto :spreadplot-supervisor 
  (&optional (obj-id nil set))
  (when set (setf (slot-value 'spreadplot-supervisor) obj-id))
  (slot-value 'spreadplot-supervisor))

(defmeth iter-plot-proto :rsq?  (&optional (nilt nil set))
  (when set (setf (slot-value 'rsq?) nilt))
  (slot-value 'rsq?))

(defmeth iter-plot-proto :showing (&optional (obj-id nil set)) 
  (when set (setf (slot-value 'showing) obj-id)) 
  (slot-value 'showing))

(defmeth iter-plot-proto :diff-plot (&optional (obj-id nil set)) 
  (when set (setf (slot-value 'diff-plot) obj-id)) 
  (slot-value 'diff-plot))

(defmeth iter-plot-proto :show-plot ()
  (send self :show-window)
  (send self :showing t))

(defmeth iter-plot-proto :close ()
  (send (send self :spreadplot-supervisor) :close-dialog self)
  )
(defmeth iter-plot-proto :do-brush-motion (x y)
  (call-next-method x y)
  (send self :brush x y 30 5))

(defmeth iter-plot-proto :iter8 ()
  (let* ((ssp (send self :spreadplot-supervisor))
         (lsmt (send ssp :transformation-plot))
         (rsq? (send self :rsq?)))
    (cond 
      (rsq?
       (send lsmt :prepare-for-lsmt-iter)
       (send ssp :iterate2 1))
      (t (send ssp :iterate3)))))


(defmeth iter-plot-proto :update-plot (msp)
  (let* ((mod (send msp :model))
         (model (send mod :robust-model))
         (iter-info (send self :get-iter-plot-info mod))
         (iteration-list nil)
         (iter-list nil)
         ; (wl (remove 'nil (send model :weight-list)))
         ; (wl-mat (make-array (list niter nobs) :initial-contents wl))
         (wl-mat (first iter-info))
         (wl (column-list wl-mat))
         (niter (array-dimension wl-mat 0))
         (len niter)
         (nobs (array-dimension wl-mat 1))
         (pt-labels (second iter-info))
         (index 0)
         (indices (iseq niter))
         (color 'black)
         (nptsb4 (send self :num-points))
         (pt-colors (third iter-info))        
         )
    (when 
     (> niter 0)
     (send self :start-buffering)
     (send self :clear-lines)
     (dotimes 
      (k nobs)
      (cond 
        ((send self :diff-plot)
         (when (and (= nptsb4 0) (> niter 1))
               (send self :add-points 
                     (list (repeat 1 nobs)
                           (abs (- (row wl-mat 0)
                                   (row wl-mat 1))))
                     :point-labels pt-labels)
               (send self :point-color (iseq nobs) pt-colors)
               )
         (send self :add-lines (rest indices) 
               (abs (difference (select wl k)))
               :color (if (listp pt-colors)
                          (select pt-colors k) 'blue) :draw nil)
         )
        (t
         (when (and (= nptsb4 0) (> niter 1))
               (send self :add-points 
                     (list (repeat 1 nobs) (row wl-mat 1))
                     :point-labels pt-labels)
               (send self :point-color (iseq nobs) pt-colors)
               )
         (send self :add-lines indices (select wl k)
               :color (if (listp pt-colors) 
                          (select pt-colors k) 'blue) 
               :draw nil))))
     (send self :adjust-to-data)
     
     (cond 
       ((< niter 6)
        (send self :range 0 0 5)
        (send self :x-axis t t 6))
       (t (setf gnr (get-nice-range 0 (1- niter) 5))
          (send self :range 0 0 (second gnr))
          (send self :x-axis t t (third gnr))))
     (send self :buffer-to-screen))
    ))


(defmeth iter-plot-proto :get-iter-plot-info (mod)
  (if (send self :rsq?)
      (send self :get-rsq-plot-info mod)
      (send self :get-rob-plot-info mod)))
     
(defmeth iter-plot-proto :get-rob-plot-info (mod)
  (let* ((model (send mod :robust-model))
         (wl (remove 'nil (send model :weight-list)))
         (niter (length wl))
         (nobs (send mod :active-nobs))
         (wl-mat (make-array (list niter nobs) :initial-contents wl))
         (obs-labels (send mod :active-labels))
         )
    (list wl-mat obs-labels (repeat 'blue nobs))))

(defmeth iter-plot-proto :get-rsq-plot-info (mod)
  (let* ((model (send mod :morals-model))
         (iv-labels (select (send mod :variables) (send mod :iv)))
         (nvar (length iv-labels))
         (niter (+ (send model :count) 1))
         (rsq-list (send model :rsq-list))
         (beta-mat (make-array (list niter nvar) 
                   :initial-contents (send model :standardized-beta-list)))
         (rsq-beta-mat (bind-columns rsq-list beta-mat))
         )
    (list rsq-beta-mat 
          (combine "R-Sq" iv-labels) 
          (combine 'red (repeat 'blue nvar)))
    ))

(defmeth iter-plot-proto :rsq-links ()
  (if (member self *rsq-plots*) *rsq-plots*))

(defmeth iter-plot-proto :rsq-linked (&optional (link nil set))
  (when set (setf *rsq-plots* (if link (cons self *rsq-plots*)
                                  (remove self *rsq-plots*)))
            (call-next-method link))
  (call-next-method))

(defmeth iter-plot-proto :obs-plots ()
  (let ((splot (send self :spreadplot-supervisor)))
    (when splot (send splot :obs-plots))))        

(defmeth iter-plot-proto :links ()
  (let ((obs-plots (send self :obs-plots)))
    (if (member self obs-plots) obs-plots)))

(defmeth iter-plot-proto :linked (&optional (link nil set))
  (let ((obs-plots (send self :obs-plots)))
    (when set (setf obs-plots (if link (cons self obs-plots)
                                  (remove self obs-plots)))
          (call-next-method link))
    (call-next-method)))

;;=========================================
;; Robust Regression Plot
;;=========================================


(defproto robust-reg-plot-proto '(spreadplot-supervisor showing) ()
  vista-scatterplot-proto ())

(defmeth robust-reg-plot-proto :spreadplot-supervisor (&optional (obj-id nil set))
  (when set (setf (slot-value 'spreadplot-supervisor) obj-id))
  (slot-value 'spreadplot-supervisor))

(defmeth robust-reg-plot-proto :showing (&optional (obj-id nil set)) 
  (when set (setf (slot-value 'showing) obj-id)) 
  (slot-value 'showing))

(defmeth robust-reg-plot-proto :show-plot ()
  (send self :show-window)
  (send self :showing t))

(defmeth robust-reg-plot-proto :close ()
  (send (send self :spreadplot-supervisor) :close-dialog self)
  )

(defmeth robust-reg-plot-proto :iter8 ()
  (send (send self :spreadplot-supervisor) :iterate3)
  )

(defmeth robust-reg-plot-proto :isnew (ssp &rest args
                                       &key
                                       (title "Regression and Fit")
                                       (menu-title "Fit")
                                       (scale 'nil)
                                       (show 't))
  (send self :spreadplot-supervisor ssp)
  (apply #'call-next-method 2
         (append args `(:title ,title :menu-title ,menu-title :show nil)))
  (send self :use-color t))


(defmeth robust-reg-plot-proto :obs-plots ()
  (let ((splot (send self :spreadplot-supervisor)))
    (when splot (send splot :obs-plots))))        

(defmeth robust-reg-plot-proto :links ()
  (let ((obs-plots (send self :obs-plots)))
    (if (member self obs-plots) obs-plots)))

(defmeth robust-reg-plot-proto :linked (&optional (link nil set))
  (let ((obs-plots (send self :obs-plots)))
    (when set (setf obs-plots (if link (cons self obs-plots)
                                  (remove self obs-plots)))
          (call-next-method link))
    (call-next-method)))

;;=========================================
;; obs Plot
;;=========================================

(defproto obs-list-proto '(spreadplot-supervisor showing) ()
  name-list-proto ())


(defmeth obs-list-proto :isnew (ssp &rest args)
  (let* (
         (obs (send current-data :labels))
         (nobs (length obs))
         (ol (call-next-method 0 :show nil))
         )
  (send ol :spreadplot-supervisor ssp)
  (send ol :add-points (list (iseq nobs)))
  (send ol :point-label (iseq nobs) obs)
  (send ol :title "Observations")
  (send ol :adjust-to-data)
 ol))

(defmeth obs-list-proto :spreadplot-supervisor (&optional (obj-id nil set)) 
  (when set (setf (slot-value 'spreadplot-supervisor) obj-id)) 
  (slot-value 'spreadplot-supervisor))


(defmeth obs-list-proto :showing (&optional (obj-id nil set)) 
  (when set (setf (slot-value 'showing) obj-id)) 
  (slot-value 'showing))


(defmeth obs-list-proto :show-plot ()
  (send self :show-window)
  (send self :showing t))


(defmeth obs-list-proto :close ()
  (send (send self :spreadplot-supervisor) :close-dialog self)
  )


(defmeth obs-list-proto :obs-plots ()
  (let ((splot (send self :spreadplot-supervisor)))
    (when splot (send splot :obs-plots))))        

(defmeth obs-list-proto :links ()
  (let ((obs-plots (send self :obs-plots)))
    (if (member self obs-plots) obs-plots)))

(defmeth obs-list-proto :linked (&optional (link nil set))
  (let ((obs-plots (send self :obs-plots)))
    (when set (setf obs-plots (if link (cons self obs-plots)
                                  (remove self obs-plots)))
          (call-next-method link))
    (call-next-method)))